home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / equel / display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-12-31  |  7.0 KB  |  336 lines

  1. # include    <stdio.h>
  2. # include    "constants.h"
  3. # include    "globals.h"
  4. # include    <setjmp.h>
  5. # include    <sccs.h>
  6.  
  7. SCCSID(@(#)display.c    8.1    12/31/84)
  8.  
  9. /*
  10. **  DISPLAY.C -- display manipulation routines
  11. **
  12. **    a display is a list of strings, the symbol
  13. **    space Symsp is impemented by means of displays.
  14. **
  15. **    Required By:
  16. **        Lexical analysis routines to add to the symbol space
  17. **        semantic productions to manipulate input
  18. */
  19.  
  20.  
  21.  
  22.  
  23.     /* this avoids having to specify &Cv_display in the semantic
  24.      * routines, by making Cv_display a pointer to the pertinent
  25.      * display structure.
  26.      */
  27. struct display    *Cv_display    = &Displays [0];
  28.  
  29. /*
  30. **  ENTER_DISPLAY -- enter a new string into a display
  31. **
  32. **    Parameters:
  33. **        disp -- display to be added to
  34. **        string -- string to add
  35. **
  36. **    Returns:
  37. **        pointer to new disp_node structure.
  38. **
  39. **    Side Effects:
  40. **        allocates a new disp_node structispl
  41. **        Expects a dynamic "string", i.e. one that it can 
  42. **        dispose of as it wishes, so it is the users responsability
  43. **        to allocate space for this string.
  44. **        If the string passed is 0, the string
  45. **        "ERROR_TOKEN" is substituted, and a message is printed,
  46. **        so a caller may call enter_display with the return of an
  47. **        salloc() directly.
  48. **        If no space is available for the allocation of the
  49. **        new node, an error message is given, and a reset(III)
  50. **        is performed (this should goto equel()[main.c])
  51. **
  52. **    Called By:
  53. **        add_sym() -- to add a token to the Symsp
  54. **        the semantic productions -- for manipulating usages
  55. **            of C variables.
  56. */
  57.  
  58.  
  59. struct disp_node *enter_display(disp, string)
  60. struct display    *disp;
  61. char        *string;
  62. {
  63.     register struct display        *d;
  64.     register struct disp_node    *node;
  65.     extern    jmp_buf            Jmpbuf;
  66.  
  67.     node = (struct disp_node *)nalloc(sizeof *node);
  68.     if (node == 0)
  69.     {
  70.         yysemerr("symbol space overflow", string);
  71.         longjmp(Jmpbuf,1);
  72.     }
  73.     d = disp;
  74.     if (!d->disp_first)
  75.         d->disp_first = d->disp_last = node;
  76.     else
  77.     {
  78.         d->disp_last->d_next = node;
  79.         d->disp_last = node;
  80.     }
  81.     node->d_next = 0;
  82.     if (!(node->d_elm = string))
  83.     {
  84.         yysemerr("alloc error in display", 0);
  85.         node->d_elm = "ERROR_TOKEN";
  86.     }
  87.     return (node);
  88. }
  89.  
  90. /*
  91. **  ADDSYM -- add a token to the symbol space
  92. **
  93. **    The node's .d_line field is set to the value of yyline,
  94. **    which, if this routine is called from a lexical routine
  95. **    taking lexemes that can't include newlines (and back them up),
  96. **    is the line the lexeme was read from. This fact is used
  97. **    be yyserror() [yyerror.c] to report accurate line numbers
  98. **    for errors.
  99. **
  100. **    Parameters:
  101. **        s -- string to add
  102. **
  103. **    Returns:
  104. **        pointer to node added
  105. */
  106.  
  107.  
  108.  
  109. struct disp_node *addsym(s)
  110. char        *s;
  111. {
  112.     register struct disp_node    *d;
  113.  
  114.     d = enter_display(&Symsp, s);
  115.     d->d_line = yyline;
  116.     return (d);
  117. }
  118.  
  119. /*
  120. **  FREE_DISPLAY -- frees all elements of a display
  121. **
  122. **    Parameters:
  123. **        disp -- the display to free
  124. */
  125.  
  126.  
  127.  
  128.  
  129.  
  130. free_display(disp)
  131. struct display    *disp;
  132. {
  133.     register struct display        *d;
  134.     register struct disp_node    *f, *n;
  135.  
  136.     d = disp;
  137.     for (f = d->disp_first; f; f = n)
  138.     {
  139.         n = f->d_next;
  140.         xfree(f->d_elm);
  141.         xfree(f);
  142.     }
  143.     d->disp_first = d->disp_last = 0;
  144. }
  145.  
  146. /*
  147. **  SYSMSPFREE -- Frees symbol space
  148. **    Symspfree frees all the symbol table, EXCEPT
  149. **    for the last element in it, as this is the lookahead
  150. **    element. That is to say, the element which forced reduction
  151. **    to the non-terminal program, which called on symspfree()
  152. **
  153. **    Requires:
  154. **        Symsp -- to free it
  155. **
  156. **    Called By:
  157. **        argproc()
  158. **        semantic routines (nonterminal "program")
  159. */
  160.  
  161.  
  162.  
  163. symspfree()
  164. {
  165.     register struct display        *d;
  166.     register struct disp_node    *f, *n;
  167.  
  168.     d = &Symsp;
  169.     for (f = d->disp_first; f && f->d_next; f = n)
  170.     {
  171.         n = f->d_next;
  172.         xfree(f->d_elm);
  173.         xfree(f);
  174.     }
  175.     d->disp_first = d->disp_last;
  176. }
  177.  
  178. /*
  179. **  W_DISPLAY -- write out the contents of a display
  180. **
  181. **    Parameters:
  182. **        disp -- display to take write out
  183. **
  184. **    Side Effects:
  185. **        Writes onto Out_file
  186. **        the contents of the display,
  187. **        each string is comsidered a separate
  188. **        word to be written out(so w_raw may
  189. **        break a line between words).
  190. **        Calls are made to w_op() and w_key() so as 
  191. **        to have the minimum number of spaces in the text.
  192. **
  193. **    Requires:
  194. **        w_op() -- to write out operator terminated
  195. **            strings
  196. **        w_key() -- to write out KEYCHAR terminated 
  197. **            strings
  198. **
  199. **    Called By:
  200. **        semantic productions dealing with usage of
  201. **        C variables.
  202. */
  203.  
  204.  
  205.  
  206. w_display(disp)
  207. struct display        *disp;
  208. {
  209.     register struct disp_node    *n;
  210.  
  211.     for (n = disp->disp_first; n; n = n->d_next)
  212.     {
  213.         switch (Cmap [n->d_elm [length(n->d_elm) - 1]])
  214.         {
  215.  
  216.           case OPATR :
  217.           case PUNCT :
  218.             w_op(n->d_elm);
  219.             break;
  220.  
  221.           default :
  222.             w_key(n->d_elm);
  223.             break;
  224.         }
  225.     }
  226. }
  227. /*
  228. **  EAT_DISPLAY -- enter text from In_file into a display
  229. **    Enters all text gotten through getch() [getch.c]
  230. **    lying between one character delimiters, which may
  231. **    be nested, into a display or w_op()'s it.
  232. **    eat_display() assumes that when it is called a 
  233. **    "left_ch" has just been seen. It will "eat" up to 
  234. **    MAXSTRING characters.
  235. **    Newline is played with because :
  236. **        a) a newline may have been read by eat_display
  237. **           instead of yylex(), therefore if eat_display
  238. **           stops there, yylex() must know that a newline
  239. **           has just been seen and it must test for C_CODE.
  240. **        b) Newline may have to be set to 0 if an include()
  241. **           was done which sets it to 1, and no yylex() was
  242. **           done afterwards to reset it.
  243. **
  244. **        NOTE : This playing with Newline is needed because 
  245. **        yylex() and not getch() maintains Newline. If getch()
  246. **        maintained Newline then it would be automatically right.
  247. **
  248. **    Parameters:
  249. **        disp -- display to add elements to if != 0 else
  250. **            characters are written out.
  251. **        left_ch -- left delimiter character
  252. **        right_ch -- right delimiter character
  253. **
  254. **    Side Effects:
  255. **        advances input to after the close of the
  256. **        left_ch, right_ch pair.
  257. **        may back up 2 characters.
  258. **
  259. **    Called By:
  260. **        semantic routines dealing with array subscription
  261. **
  262. **    Bugs:
  263. **        #include's encountered, are treated wrongly
  264. **        because the "#include ...c.h" is put out immediately,
  265. **        while the display is put out only later.
  266. */
  267.  
  268.  
  269. eat_display(disp, left_ch, right_ch)
  270. struct display    *disp;
  271. char        left_ch;
  272. char        right_ch;
  273. {
  274.     char        buf [MAXSTRING + 1];
  275.     register char    *cp;
  276.     register    level;
  277.     register    i;
  278.     char        pk;
  279.     char        r_c [2];
  280.  
  281.     cp = buf;
  282.     level = i = 1;
  283.     *cp = left_ch;
  284.     do
  285.     {
  286.         i++;
  287.         if (i >= sizeof buf)
  288.         {
  289.             yysemerr("display too long", 0);
  290.             break;
  291.         }
  292.         if ((*++cp = getch()) == left_ch)
  293.             level++;
  294.         else if (*cp == right_ch)
  295.             level -= 1;
  296.         else if (*cp == EOF_TOK)
  297.         {
  298.             backup(*cp);
  299. missing :
  300.             r_c [1] = '\0';
  301.             r_c [0] = right_ch;
  302.             yysemerr("missing closing character", r_c);
  303.             *cp = right_ch;
  304.             /* make next line be read as possible
  305.              * C_CODE by yylex() [yylex.c]
  306.              */
  307.             Newline = 1;
  308.             break;
  309.         }
  310.         else if (*cp == '\n')
  311.         {
  312.             /* test that next line is valid equel line,
  313.              * and strip "##"
  314.              */
  315.             if ((pk = getch()) != '#')
  316.             {
  317.                 backup(pk);
  318.                 goto missing;
  319.             }
  320.             if ((pk = getch()) != '#')
  321.             {
  322.                 backup(pk);
  323.                 backup('#');
  324.                 goto missing;
  325.             }
  326.         }
  327.     }  while (*cp != right_ch || level > 0);
  328.     if (level == 0)
  329.         Newline = 0;
  330.     *++cp = '\0';
  331.     if (disp)
  332.         enter_display(disp, salloc(buf));
  333.     else
  334.         w_op(buf);
  335. }
  336.